package com.bmf.module.examination.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bmf.constant.AdminResultEnum;
import com.bmf.core.result.PageResponse;
import com.bmf.enums.QuestionDifficultyLevel;
import com.bmf.module.examination.entity.SelectionStrategy;
import com.bmf.module.examination.entity.SelectionStrategyQuestion;
import com.bmf.module.examination.mapper.SelectionStrategyQuestionMapper;
import com.bmf.module.examination.service.SelectionStrategyQuestionService;
import com.bmf.module.examination.service.SelectionStrategyService;
import com.bmf.module.examination.vo.SelectionStrategyQuestionCreateVo;
import com.bmf.module.examination.vo.SelectionStrategyQuestionPageVo;
import com.bmf.module.examination.vo.SelectionStrategyQuestionResultVo;
import com.bmf.module.examination.vo.SelectionStrategyResultVo;
import com.bmf.module.testQuestions.entity.SmallQuestion;
import com.bmf.module.testQuestions.service.SmallQuestionService;
import com.bmf.module.testQuestions.vo.QuestionResultVo;
import com.bmf.utils.BeanCopyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * (SelectionStrategyQuestion)表服务实现类
 *
 * @author makejava
 * @since 2022-12-02 10:59:52
 */
@Service("selectionStrategyQuestionService")
public class SelectionStrategyQuestionServiceImpl extends ServiceImpl<SelectionStrategyQuestionMapper, SelectionStrategyQuestion> implements SelectionStrategyQuestionService {

    @Autowired
    private SmallQuestionService smallQuestionService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insert(List<SelectionStrategyQuestionCreateVo> selectionStrategyQuestionCreateVos) {
        if(CollUtil.isEmpty(selectionStrategyQuestionCreateVos)){
            return;
        }
        //1.如果是分类添加，判断有无题目在此分类下，无题目添加失败
        if(selectionStrategyQuestionCreateVos.size()==1&&selectionStrategyQuestionCreateVos.get(0).getSmallQuestionId()==null){
            SelectionStrategyQuestionCreateVo selectionStrategyQuestionCreateVo = selectionStrategyQuestionCreateVos.get(0);
            boolean b = smallQuestionService.existByType(selectionStrategyQuestionCreateVo.getTopic(),selectionStrategyQuestionCreateVo.getQuestionType());
            AdminResultEnum.NO_QUESTION.assertIsTrue(b);
            //1.1避免重复添加相同的分类
            //1.1.1 查询
            LambdaQueryWrapper<SelectionStrategyQuestion> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SelectionStrategyQuestion::getExaminationId, selectionStrategyQuestionCreateVos.get(0).getExaminationId())
                    .isNull(SelectionStrategyQuestion::getSmallQuestionId);
            List<SelectionStrategyQuestion> list = list(wrapper);
            if(CollUtil.isNotEmpty(list)){
                //1.1.2判断
                list.forEach(s->{
                    AdminResultEnum.SAME_QUESTION_TYPE.assertIsTrue(!(s.getQuestionType()==selectionStrategyQuestionCreateVos.get(0).getQuestionType()&&s.getTopic()==selectionStrategyQuestionCreateVos.get(0).getTopic()));
                });
            }
        }
        List<SelectionStrategyQuestion> questions = BeanCopyUtils.copyBeanList(selectionStrategyQuestionCreateVos, SelectionStrategyQuestion.class);
        saveBatch(questions);
    }

    @Override
    public PageResponse<SelectionStrategyQuestionResultVo> selectAll(SelectionStrategyQuestionPageVo selectionStrategyQuestionPageVo) {
        LambdaQueryWrapper<SelectionStrategyQuestion> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SelectionStrategyQuestion::getSelectionStrategyId, selectionStrategyQuestionPageVo.getSelectionStrategyId());
        Page<SelectionStrategyQuestion> page = new Page(selectionStrategyQuestionPageVo.getPageNo(),selectionStrategyQuestionPageVo.getPageSize());
        page(page,wrapper);
        List<SelectionStrategyQuestion> list = page.getRecords();
        if(CollUtil.isEmpty(list)){
            return new PageResponse<>(null,page.getTotal(),selectionStrategyQuestionPageVo.getPageNo(),selectionStrategyQuestionPageVo.getPageSize());
        }
        List<Integer> ids = list.stream().map(SelectionStrategyQuestion::getSmallQuestionId).collect(Collectors.toList());
        LambdaQueryWrapper<SmallQuestion> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.in(SmallQuestion::getId, ids);
        List<SmallQuestion> list1 = smallQuestionService.list(wrapper1);
        if(CollUtil.isNotEmpty(list1)) {
            Map<Integer, SmallQuestion> collect = list1.stream().collect(Collectors.toMap(SmallQuestion::getId, Function.identity()));
            List<SelectionStrategyQuestionResultVo> collect1 = list.stream().map(s -> BeanCopyUtils.copyBean(s, SelectionStrategyQuestionResultVo.class))
                    .peek(s -> s.setQuestionResultVo(BeanCopyUtils.copyBean(collect.get(s.getSmallQuestionId()), QuestionResultVo.class)))
                    .collect(Collectors.toList());
            return new PageResponse<>(collect1,page.getTotal(),selectionStrategyQuestionPageVo.getPageNo(),selectionStrategyQuestionPageVo.getPageSize());
        }
        return new PageResponse<>(BeanCopyUtils.copyBeanList(list,SelectionStrategyQuestionResultVo.class),page.getTotal(),selectionStrategyQuestionPageVo.getPageNo(),selectionStrategyQuestionPageVo.getPageSize());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> ids) {
        removeByIds(ids);
    }

    @Override
    public List<SelectionStrategyQuestion> getBySelectionStrategyId(Integer selectionStrategyId) {
        LambdaQueryWrapper<SelectionStrategyQuestion> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SelectionStrategyQuestion::getSelectionStrategyId, selectionStrategyId);
        return list(wrapper);
    }

    @Override
    public Map<Integer, Map<Integer, Long>> getCountMapByExaminationId(Integer examinationId) {
        LambdaQueryWrapper<SelectionStrategyQuestion> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(SelectionStrategyQuestion::getId,SelectionStrategyQuestion::getDifficultyLevel
                ,SelectionStrategyQuestion::getQuestionType,SelectionStrategyQuestion::getTopic,SelectionStrategyQuestion::getSmallQuestionId,SelectionStrategyQuestion::getSelectionStrategyId)
                .eq(SelectionStrategyQuestion::getExaminationId, examinationId);
        List<SelectionStrategyQuestion> list = list(wrapper);
        if(CollUtil.isEmpty(list)){
            return null;
        }
        List<Integer> ids = list.stream().map(SelectionStrategyQuestion::getSmallQuestionId).filter(s -> s != null).collect(Collectors.toList());
        Map<Integer, List<SelectionStrategyQuestion>> map = list.stream().collect(Collectors.groupingBy(SelectionStrategyQuestion::getSelectionStrategyId));
        Map<Integer,Map<Integer, Long>> result = new LinkedHashMap<>();
        map.entrySet().stream().forEach(s->{
            List<SelectionStrategyQuestion> value = s.getValue();
            //是类型添加题目
            if(value.size()==1&&value.get(0).getDifficultyLevel()==null){
                //查数据库
                LambdaQueryWrapper<SmallQuestion> wrapper1 = new LambdaQueryWrapper<>();
                wrapper1.select(SmallQuestion::getId,SmallQuestion::getDifficultyLevel).eq(SmallQuestion::getQuestionType,value.get(0).getQuestionType())
                        .eq(SmallQuestion::getType, value.get(0).getTopic());
                if(CollUtil.isNotEmpty(ids)){
                    wrapper1.notIn(SmallQuestion::getId, ids);
                }
                List<SmallQuestion> list1 = smallQuestionService.list(wrapper1);
                if(CollUtil.isNotEmpty(list1)){
                    Map<Integer, Long> collect = list1.stream().collect(Collectors.groupingBy(SmallQuestion::getDifficultyLevel, Collectors.counting()));
                    result.put(s.getKey(),collect);
                }
            }else{
                Map<Integer, Long> collect = value.stream().filter(k->k.getDifficultyLevel()!=null).collect(Collectors.groupingBy(SelectionStrategyQuestion::getDifficultyLevel, Collectors.counting()));
                result.put(s.getKey(),collect);
            }
        });
        return result;
    }

    @Override
    public void removeBySelectionStrategyIds(List<Long> ids) {
        LambdaQueryWrapper<SelectionStrategyQuestion> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SelectionStrategyQuestion::getSelectionStrategyId, ids);
        remove(wrapper);
    }

    @Override
    public void deleteBySmallQuestionIds(List<Integer> ids) {
        LambdaQueryWrapper<SelectionStrategyQuestion> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SelectionStrategyQuestion::getSmallQuestionId, ids);
        remove(wrapper);
    }

    @Override
    public void deleteByExaminationIds(List<Integer> ids) {
        LambdaQueryWrapper<SelectionStrategyQuestion> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SelectionStrategyQuestion::getExaminationId, ids);
        remove(wrapper);
    }
}
